12.2.2 工作原理

现在读者已经知道如何创建并使用容器覆盖网络,接下来请读者跟本书一起找出这一切背后的技术原理。

本节中某些细节特指Linux,但是同样的原理在Windows中也生效。

1.VXLAN入门

首先必须知道,Docker使用VXLAN隧道技术创建了虚拟二层覆盖网络。所以,在详解之前,先快速了解一下VXLAN。

在VXLAN的设计中,允许用户基于已经存在的三层网络结构创建虚拟的二层网络。在前面的示例中创建了一个子网掩码为10.0.0.0/24的二层网络,该网络是基于一个三层IP网络实现的,三层IP网络由172.31.1.0/24和192.168.1.0/24这两个二层网络构成。具体如图12.4所示。

79.png

图12.4 创建虚拟的二层网络

VXLAN的美妙之处在于它是一种封装技术,能使现存的路由器和网络架构看起来就像普通的IP/UDP包一样,并且处理起来毫无问题。

为了创建二层覆盖网络,VXLAN基于现有的三层IP网络创建了隧道。读者可能听过基础网络(Underlay Network)这个术语,它用于指代三层之下的基础部分。

VXLAN隧道两端都是VXLAN隧道终端(VXLAN Tunnel Endpoint, VTEP)。VTEP完成了封装和解压的步骤,以及一些功能实现所必需的操作,如图12.5所示。

2.梳理一下两个容器的示例

在前面的示例中,读者通过IP网络将两台主机连接起来。每个主机运行了一个容器,之后又为容器连接创建了一个VXLAN覆盖网络。

为了实现上述场景,在每台主机上都新建了一个Sandbox(网络命名空间)。正如前文所讲,Sandbox就像一个容器,但其中运行的不是应用,而是当前主机上独立的网络栈。

80.png

图12.5 VXLAN设计

在Sandbox内部创建了一个名为 Br0 的虚拟交换机(又称做虚拟网桥)。同时Sandbox内部还创建了一个VTEP,其中一端接入到名为 Br0 的虚拟交换机当中,另一端接入主机网络栈(VTEP)。在主机网络栈中的终端从主机所连接的基础网络中获取到IP地址,并以UDP Socket的方式绑定到4789端口。不同主机上的两个VTEP通过VXLAN隧道创建了一个覆盖网络,如图12.6所示。

81.png

图12.6 不同主机的VTEP创建覆盖网络

这是VXLAN上层网络创建和使用所必需的。

接下来每个容器都会有自己的虚拟以太网( veth )适配器,并接入本地 Br0 虚拟交换机。目前拓扑结构如图12.7所示,虽然是在主机所属网络互相独立的情况下,但这样能更容易看出两个分别位于不同主机上的容器之间是如何通过VXLAN上层网络进行通信的。

82.png

图12.7 以太网( `veth` )适配器接入本地Br0虚拟交换机
3.通信示例

现在读者已经了解了基本原理,接下来跟随本书一起探究两个容器间究竟是如何通信的。

在本例中,将node1上的容器称为 C1 ,node2上的容器称为 C2 ,如图12.8所示。假设 C1 希望ping通 C2 ,类似前面章节中的示例。

C1 发起ping请求,目标IP为 C2 的地址 10.0.0.4 。该请求的流量通过连接到 Br0 虚拟交换机的veth接口发出。虚拟交换机并不知道将包发送到哪里,因为在虚拟交换机的MAC地址映射表(ARP映射表)中并没有与当前目的IP对应的MAC地址。所以虚拟交换机会将该包发送到其上的全部端口。连接到 Br0 的VTEP接口知道如何转发这个数据帧,所以会将自己的MAC地址返回。这就是一个代理ARP响应,并且虚拟交换机 Br0 根据返回结果学会了如何转发该包。接下来虚拟交换机会更新自己的ARP映射表,将10.0.0.4映射到本地VTEP的MAC地址上。

现在 Br0 交换机已经学会如何转发目标为 C2 的流量,接下来所有发送到 C2 的包都会被直接转发到VTEP接口。VTEP接口知道 C2 ,是因为所有新启动的容器都会将自己的网络详情采用网络内置Gossip协议发送给相同Swarm集群内的其他节点。

83.png

图12.8 为容器设置了IP地址

交换机会将包转发到VTEP接口,VTEP完成数据帧的封装,这样就能在底层网络传输。具体来说,封装操作就是把VXLAN Header信息添加以太帧当中。

VXLAN Header信息包含了VXLAN网络ID(VNID),其作用是记录VLAN到VXLAN的映射关系。每个VLAN都对应一个VNID,以便包可以在解析后被转发到正确的VLAN。封装的时候会将数据帧放到UDP包中,并设置UDP的目的IP字段为node2节点的VTEP的IP地址,同时设置UDP Socket端口为4789。这种封装方式保证了底层网络即使不知道任何关于VXLAN的信息,也可以完成数据传输。

当包到达node2之后,内核发现目的端口为UDP端口4789,同时还知道存在VTEP接口绑定到该Socket。所以内核将包发给VTEP,由VTEP读取VNID,解压包信息,并根据VNID发送到本地名为 Br0 的连接到VLAN的交换机。在该交换机上,包被发送给容器C2。

以上大体介绍了Docker覆盖网络是如何利用VXLAN技术的。

在本节只进行了比较基础的介绍,但应该足够读者开始着手Docker生产环境的部署了。同时这些知识也足以让读者与网络团队沟通Docker基础设置中网络相关的内容了。

最后一件需要注意的是,Docker支持使用同样的覆盖网络实现三层路由。例如,读者可以创建包含两个子网的覆盖网络,Docker会负责子网间的路由。创建的命令如 docker network create --subnet=10.1.1.0/24 --subnet=11.1.1.0/24 -d overlay prod-net 。该命令会在Sandbox中创建两个虚拟交换机,默认支持路由。

results matching ""

    No results matching ""